package com.choosefine.paycenter.webgateway.pay.web.controller;

import com.choosefine.paycenter.account.dto.PaymentDto;
import com.choosefine.paycenter.common.dto.JSONResult;
import com.choosefine.paycenter.common.enums.BizzSys;
import com.choosefine.paycenter.common.enums.PayStatus;
import com.choosefine.paycenter.common.utils.JSONResultGenerator;
import com.choosefine.paycenter.common.utils.SerialNumberUtils;
import com.choosefine.paycenter.pay.dto.ChoosePayTypeDto;
import com.choosefine.paycenter.pay.dto.PayDto;
import com.choosefine.paycenter.pay.service.PaymentService;
import com.choosefine.paycenter.pay.vo.PayFromAccountBillResultVo;
import com.choosefine.paycenter.pay.vo.PayInfoVo;
import com.choosefine.paycenter.pay.vo.PayResultVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;

/**
 * 支付单
 * Comments：
 * Author：Jay Chang
 * Create Date：2017/3/17
 * Modified By：
 * Modified Date：
 * Why & What is modified：
 * Version：v1.0
 */
@Api(value = "支付",description = "张洁")
@RequestMapping("pay")
@Controller
public class PayController {
    @Autowired
    private PaymentService paymentService;

    @Autowired
    private SerialNumberUtils serialNumberUtils;

    /**
     * 创建支付单
     * @return JSONResult
     */
    @ApiOperation("创建支付单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userCode", dataType = "String", paramType = "header", required = true, value = "交易主体的租户编码"),
            @ApiImplicitParam(name = "orders[0].userCode", dataType = "String", paramType = "body", required = true, value = "业务订单中的租户编码"),
            @ApiImplicitParam(name = "orders[0].amount", dataType = "Double", paramType = "body", required = true, value = "业务订单中的交易金额"),
            @ApiImplicitParam(name = "orders[0].orderSn", dataType = "String", paramType = "body", required = true, value = "业务订单中的订单号"),
            @ApiImplicitParam(name = "orders[0].tradeMemo", dataType = "String", paramType = "body", required = true, value = "业务订单的交易备注（附言）"),
            @ApiImplicitParam(name = "bizzSys", dataType = "String",allowableValues = "LABOR,SHOP,SELF",paramType = "body", required = true, value = "业务系统标识(可选值：1.LABOR,2.SHOP)"),
            @ApiImplicitParam(name = "bizzSn", dataType = "String", paramType = "body", required = true, value = "业务系统业务流水号"),
            @ApiImplicitParam(name = "tradeType", dataType = "String", allowableValues = "TRANSFER,PAY_AGENT,SALARY,SHOPPING,SUBPACKAGE,REFUND",paramType = "body", required = true, value = "交易类型"),
            @ApiImplicitParam(name = "amount", dataType = "Double", paramType = "body", required = true, value = "交易总金额"),
            @ApiImplicitParam(name = "bizzCallbackUrl", dataType = "String", paramType = "body", required = true, value = "业务系统回调url"),
            @ApiImplicitParam(name = "operName", dataType = "String", paramType = "body", required = true, value = "操作员名称"),
    })
    @PostMapping("payment")
    @ResponseBody
    public JSONResult createPayment(@RequestHeader("userCode") @NotBlank String userCode,@Validated({PaymentService.CreatePayment.class}) @RequestBody PaymentDto paymentDto){
        paymentDto.setUserCode(userCode);
        String paySn = paymentService.createPayment(paymentDto);
        return JSONResultGenerator.buildOperSuccessResult(paySn);
    }

    @ApiOperation("选择支付方式")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bizzSys",dataType = "String",allowableValues = "LABOR,SHOP,SELF",paramType = "body",required = true,value = "业务系统标识(可选值：LABOR,SHOP,SELF)"),
            @ApiImplicitParam(name = "bizzSn",dataType = "String",paramType = "body",required = true,value = "业务系统流水号"),
            @ApiImplicitParam(name = "channel",dataType = "String",paramType = "body",required = true,value = "支付通道"),
            @ApiImplicitParam(name = "payType",dataType = "String",paramType = "body",required = true,value = "支付类型"),
            @ApiImplicitParam(name = "returnUrl",dataType = "String",paramType = "body",required = false,value = "支付成功后的页面回调url(APP端不需要设置)"),
    })
    //其实这里叫做选择支付类型更妥当
    @PutMapping("payType")
    @ResponseBody
    public JSONResult choosePayWay(@RequestHeader("userCode") @NotBlank  String userCode,@Validated({PaymentService.ChoosePayType.class}) @RequestBody ChoosePayTypeDto choosePayTypeDto){
        choosePayTypeDto.setUserCode(userCode);
        int result = paymentService.choosePayType(choosePayTypeDto);
        return JSONResultGenerator.buildOperSuccessResult(result);
    }

    @ApiOperation("支付")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userCode",dataType = "String",paramType = "header",required = true,value = "租户编码"),
            @ApiImplicitParam(name = "bizzSys",dataType = "String",allowableValues = "LABOR,SHOP",paramType = "body",required = true,value = "业务系统标识"),
            @ApiImplicitParam(name = "bizzSn",dataType = "String",paramType = "body",required = true,value = "业务系统业务流水号"),
            @ApiImplicitParam(name = "payPass",dataType = "String",paramType = "body",required = true,value = "支付密码"),
    })
    @PostMapping("doPay")
    @ResponseBody
    public JSONResult doPay(@RequestHeader("userCode") @NotBlank String userCode, @Validated @RequestBody PayDto payDto) throws Exception {
        payDto.setUserCode(userCode);
        PayResultVo payResultVo = paymentService.doPay(payDto);
        return JSONResultGenerator.buildOperSuccessResult(payResultVo);
    }

    /**
     * 账单入口发起创建支付单
     * @return JSONResult
     */
    @ApiOperation("账单入口发起创建支付单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userCode", dataType = "String", paramType = "header", required = true, value = "交易主体的租户编码"),

    })
    @PostMapping("accountBill/{id}")
    @ResponseBody
    public JSONResult createPaymentFromAccountBill(@RequestHeader("userCode") @NotBlank String userCode,@PathVariable("id") Long accountBillId){
        PayFromAccountBillResultVo payFromAccountBillResultVo = paymentService.createPayment(userCode, accountBillId);
        return JSONResultGenerator.buildOperSuccessResult(payFromAccountBillResultVo);
    }

    @ApiOperation("根据业务流水号查询支付状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bizzSys",dataType = "String",allowableValues = "LABOR,SHOP",paramType = "query",required = true,value = "业务系统标识"),
            @ApiImplicitParam(name = "bizzSn",dataType = "String",paramType = "query",required = true,value = "业务系统业务流水号"),
    })
    @GetMapping("status/bizzSn")
    @ResponseBody
    public JSONResult findPaymentStatus(@NotBlank String bizzSys,@NotBlank String bizzSn){
        PayStatus payStatus = paymentService.findStatusByBizzSn(BizzSys.valueOf(bizzSys),bizzSn);
        return JSONResultGenerator.buildQuerySuccessResult(payStatus);
    }


    @ApiOperation("根据支付流水号查询支付状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "paySn",dataType = "String",paramType = "query",required = true,value = "支付流水号"),
    })
    @GetMapping("status/paySn")
    @ResponseBody
    public JSONResult findPaymentStatus(@NotBlank String paySn){
        PayStatus payStatus = paymentService.findStatusByPaySn(paySn);
        return JSONResultGenerator.buildQuerySuccessResult(payStatus);
    }

    @GetMapping("info")
    @ApiOperation("支付信息页汇总")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userCode", paramType = "header", dataType = "String", required = true, value = "交易主体账户租户编码"),
            @ApiImplicitParam(name = "bizzSn", paramType = "query", dataType = "String", required = true, value = "业务系统业务流水号"),
            @ApiImplicitParam(name = "bizzSys", paramType = "query",allowableValues = "LABOR,SHOP,SELF",dataType = "String", required = true, value = "业务系统标识:LABOR(劳务),SHOP(商城),SELF(支付系统)"),
    })
    @ResponseBody
    public JSONResult payInfoPage(@RequestHeader("userCode") @NotBlank String userCode,@NotBlank String bizzSn,@NotNull BizzSys bizzSys){
        // 支付页面信息
        PayInfoVo payInfoVo = paymentService.findPayInfo(userCode, bizzSys,bizzSn);
        return JSONResultGenerator.buildQuerySuccessResult(payInfoVo);
    }


    @GetMapping("transfer/sn")
    @ApiOperation("获取普通转账流水号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userCode", paramType = "header", dataType = "String", required = true, value = "账户租户编码"),
    })
    @ResponseBody
    public JSONResult createSelfTransferSn(@RequestHeader("userCode") String userCode){
        return JSONResultGenerator.buildQuerySuccessResult(serialNumberUtils.getSelfNormalTransferSn());
    }
}
